package com.zgw.his.design.resource.dialog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.zgw.his.common.ValueUtil;
import com.zgw.his.design.common.EditTable;
import com.zgw.his.design.common.LayoutUtil;
import com.zgw.his.design.common.RcpResourceManager;
import com.zgw.his.design.common.SWTResourceManager;
import com.zgw.his.design.resource.BaseResource;
import com.zgw.his.server.emr.IEmrService;
import com.zgw.his.server.emr.entity.TbaseInputSelected;
import com.zgw.his.server.emr.entity.TbaseInputSelectedItem;
import com.zgw.his.server.emr.entity.TbaseInputSelectedItemId;
import com.zgw.his.server.exceptions.BusinessException;
import com.zgw.his.server.util.SpringBeanFactory;

/**
 * 数据源项目设置
 * 
 * @see
 * */
public class InputSelectedSetDlg extends Dialog {
	private static final IEmrService service = SpringBeanFactory
			.getServiceBean(IEmrService.class);
	protected Object result;
	protected Shell shell;
	private EditTable table;
	private SashForm sashForm;
	private Text text;
	private Tree tree;
	private Button btns;
	private Long sid;
	// =============================
	// Image
	// =============================
	private static final Image imageFolder = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/folder.gif");
	private static final Image imageFile = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/input_item.gif");

	private static final Image imageAdd = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/add.gif");
	private static final Image imageDel = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/delete.gif");

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public InputSelectedSetDlg(Shell parent, int style) {
		super(parent, style);
		setText("输入可选项设置");
	}

	public InputSelectedSetDlg(Shell parent, int style, Long sid) {
		super(parent, style);
		setText("输入可选项设置");
		this.sid = sid;
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public Object open() {
		createContents();
		Display display = getParent().getDisplay();
		LayoutUtil.centerShell(display, shell);
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shell = new Shell(getParent(), SWT.BORDER | SWT.MAX | SWT.TITLE
				| SWT.APPLICATION_MODAL | SWT.RESIZE);
		shell.setSize(600, 538);
		shell.setText("可选项设置");
		shell.setLayout(new FormLayout());

		sashForm = new SashForm(shell, SWT.SMOOTH);
		{
			FormData formData = new FormData();
			formData.top = new FormAttachment(0);
			formData.bottom = new FormAttachment(100, -50);
			formData.left = new FormAttachment(0);
			formData.right = new FormAttachment(100);
			sashForm.setLayoutData(formData);
		}
		sashForm.setSashWidth(2);
		{
			Composite composite = new Composite(sashForm, SWT.NONE);
			composite.setBackground(SWTResourceManager
					.getColor(SWT.COLOR_LIST_BACKGROUND));
			composite.setLayout(new GridLayout(1, false));
			text = new Text(composite, SWT.BORDER);
			text.setMessage("在此输入名称或编号进行查找");
			{
				GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true,
						false, 1, 1);
				gridData.heightHint = 18;
				text.setLayoutData(gridData);
			}
			tree = new Tree(composite, SWT.NONE);
			tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
					1));
		}
		{
			Composite composite = new Composite(sashForm, SWT.NONE);
			GridLayout gridLayout = new GridLayout(4, false);
			gridLayout.marginHeight = 0;
			gridLayout.marginWidth = 0;
			gridLayout.marginTop = 10;
			composite.setLayout(gridLayout);
			Label label_0 = new Label(composite, SWT.SEPARATOR | SWT.VERTICAL);
			label_0.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false,
					false, 1, 1));
			table = new EditTable(composite, SWT.H_SCROLL | SWT.V_SCROLL);
			table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1,
					1));
			table.setHeaderVisible(true);
			table.setLinesVisible(true);
			table.setFont(RcpResourceManager.getFont("宋体", 11, SWT.NONE));
			{
				TableColumn tableColumn = new TableColumn(table, SWT.NONE);
				tableColumn.setWidth(106);
				tableColumn.setText("显示名称");
			}
			{
				TableColumn tableColumn = new TableColumn(table, SWT.NONE);
				tableColumn.setWidth(110);
				tableColumn.setText("实际值");
			}
			Label label_1 = new Label(composite, SWT.SEPARATOR | SWT.VERTICAL);
			label_1.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false,
					false, 1, 1));

			ToolBar toolBar = new ToolBar(composite, SWT.FLAT | SWT.VERTICAL);
			toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
					false, 1, 1));
			{
				ToolItem toolItem = new ToolItem(toolBar, SWT.NONE);
				toolItem.setToolTipText("插入一行");
				toolItem.setText("新增");
				toolItem.setImage(imageAdd);
				toolItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						doAddItem();
					}
				});
			}
			{
				ToolItem toolItem = new ToolItem(toolBar, SWT.NONE);
				toolItem.setToolTipText("删除选中行");
				toolItem.setText("删除");
				toolItem.setImage(imageDel);
				toolItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						doDelItem();
					}
				});
			}

		}
		Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		{
			FormData formData = new FormData();
			formData.top = new FormAttachment(sashForm, 0);
			formData.bottom = new FormAttachment(sashForm, 8, SWT.BOTTOM);
			formData.right = new FormAttachment(sashForm, 0, SWT.RIGHT);
			formData.left = new FormAttachment(sashForm, 0, SWT.LEFT);
			sashForm.setWeights(new int[] { 3, 7 });
			label.setLayoutData(formData);
		}
		Button btnc = new Button(shell, SWT.NONE);
		{
			FormData formData_1 = new FormData();
			formData_1.top = new FormAttachment(label, 6);
			formData_1.left = new FormAttachment(100, -80);
			formData_1.width = 70;
			formData_1.height = 25;
			btnc.setLayoutData(formData_1);
		}
		btnc.setText("  关闭&C  ");
		btnc.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				shell.close();
			}
		});
		btns = new Button(shell, SWT.NONE);
		{
			FormData formData = new FormData();
			formData.width = 70;
			formData.top = new FormAttachment(btnc, 0, SWT.TOP);
			formData.bottom = new FormAttachment(btnc, 0, SWT.BOTTOM);
			formData.right = new FormAttachment(btnc, -6);
			btns.setLayoutData(formData);
		}
		btns.setText("  保存&O  ");
		btns.setEnabled(false);
		btns.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				doSave();
			}
		});
		initializeListener();
		initializeMenu();
		if (this.sid != null) {
			text.setText(sid.toString());
			text.setSelection(1, text.getText().length());
			if (items.containsKey(sid)) {
				tree.setSelection(items.get(sid));
				doSlected();
				tree.setFocus();
			}
		} else {
			text.setText("");
		}

	}

	private void initializeMenu() {
		Menu menu = new Menu(tree);
		{
			MenuItem item = new MenuItem(menu, SWT.NONE);
			item.setText("新增项目");
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					doAddTreeItem(false);
				}
			});
		}
		{
			MenuItem item = new MenuItem(menu, SWT.NONE);
			item.setText("新增目录");
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					doAddTreeItem(true);
				}
			});
		}
		{
			MenuItem item = new MenuItem(menu, SWT.NONE);
			item.setText("删除");
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					doDelTreeItem();
				}
			});
		}
		{
			MenuItem item = new MenuItem(menu, SWT.NONE);
			item.setText("重命名");
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					doRenameTreeItem();
				}
			});
		}
		tree.setMenu(menu);
	}

	protected void doRenameTreeItem() {
		// TODO Auto- method stub

	}

	protected void doDelTreeItem() {
		TbaseInputSelected sinput = null; // Selected Input
		List<TbaseInputSelectedItem> sonItems = null;
		if (tree.getSelection().length > 0) {
			sinput = (TbaseInputSelected) tree.getSelection()[0].getData();

		}
		if (sinput != null && new Long(1).equals(sinput.getFisDir())) {
			if (tree.getSelection()[0].getItemCount() > 0) {
				MessageDialog.openWarning(shell, "警告", "不能删除存在子节点的目录");
				return;
			}
		} else if (sinput != null) {
			sonItems = BaseResource.getBaseInputSelectedItems(sinput.getFid());
		}

		try {
			if (sonItems != null && !sonItems.isEmpty()) {
				service.deleteAll(sonItems);
			}
			service.delete(sinput);
			// Delete After
			Long parentID = sinput.getFparentid();
			BaseResource.loadInput();
			fillTree(BaseResource.getBaseInputSelected());
			if (parentID != null) {
				tree.setSelection(items.get(parentID));
				items.get(parentID).setExpanded(true);
			}
		} catch (Exception e) {
			MessageDialog.openError(shell, "程序异常", "保存失败:" + e.getMessage());
			e.printStackTrace();
		}
	}

	private String getInputName() {
		InputDialog idlg = new InputDialog(shell, "新增目录", "请在些输入目录名称:", "",
				new IInputValidator() {
					public String isValid(String newText) {
						if (!ValueUtil.hasValue(newText)) {
							return "名称不能为空";
						}
						return null;
					}
				});
		String name = null;
		if (idlg.open() == InputDialog.OK) {
			name = idlg.getValue();
		}
		return name;
	}

	protected void doAddTreeItem(boolean isDir) {
		String name = getInputName();
		if (name == null)
			return;
		TbaseInputSelected input = new TbaseInputSelected();
		input.setFisDir(isDir ? 1L : 0L);
		input.setFname(name);

		TbaseInputSelected sinput = null; // Selected Input
		if (tree.getSelection().length > 0) {
			sinput = (TbaseInputSelected) tree.getSelection()[0].getData();
		}
		if (sinput != null && new Long(1).equals(sinput.getFisDir())) {
			input.setfLevel(sinput.getfLevel() != null ? sinput.getfLevel() + 1
					: 2L);
			input.setFparentid(sinput.getFid());
			input.setfOrder(new Long(tree.getSelection()[0].getItemCount()));
		} else if (sinput != null) {
			input.setfLevel(sinput.getfLevel());
			input.setFparentid(sinput.getFparentid());
			input.setfOrder(new Long(tree.getSelection()[0].getItemCount()));
		} else {
			input.setfLevel(0L);
			input.setfOrder(new Long(tree.getItemCount()));
		}

		if (input != null) {
			try {
				input = service.save(input);

				// Save After
				BaseResource.loadInput();
				fillTree(BaseResource.getBaseInputSelected());
				tree.setSelection(items.get(input.getFid()));
			} catch (Exception e) {
				MessageDialog.openError(shell, "程序异常", "新增失败" + e.getMessage());
				e.printStackTrace();
			}
		}
	}

	private void initializeListener() {
		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (tree.getItem(new Point(e.x, e.y)) == null
						&& tree.getItem(new Point(e.x + 15, e.y)) == null) {
					tree.setSelection(new TreeItem[] {});
				}
			}
		});
		tree.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (e.item != null) {
					doSlected();
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				if (e.detail <= 0 && e.item != null
						&& e.item instanceof TreeItem) {
					TreeItem item = (TreeItem) e.item;
					item.setExpanded(!item.getExpanded());
				}
			}
		});
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				try {
					doFilter(text.getText());
				} catch (Exception e1) {
					MessageDialog.openError(shell, "程序异常",
							"树节点构建失败" + e1.getMessage());
					e1.printStackTrace();
				}
			}
		});
	}

	protected void doFilter(String param) throws Exception {
		Collection<TbaseInputSelected> li = BaseResource.getBaseInputSelected();
		if (!ValueUtil.hasValue(param)) {
			fillTree(li);
			return;
		}
		ArrayList<TbaseInputSelected> result = new ArrayList<TbaseInputSelected>();
		for (TbaseInputSelected s : li) {
			if (s.getFname().indexOf(param) > -1
					|| s.getFid().toString().equals(param)) {
				if (!result.contains(s)) {
					result.add(s);
					addParent(s, result);
					addChildren(s, result, li);
				}
			}
		}
		fillTree(result);
		for (TreeItem item : items.values()) {
			item.setExpanded(true);
		}
	}

	private void addParent(TbaseInputSelected s,
			ArrayList<TbaseInputSelected> result) {
		TbaseInputSelected p = BaseResource.getInputSelected(s.getFparentid()
				+ "");
		while (p != null) {
			if (result.contains(p)) {
				break;
			}
			result.add(p);
			p = BaseResource.getInputSelected(p.getFparentid() + "");
		}
	}

	private void addChildren(TbaseInputSelected s,
			ArrayList<TbaseInputSelected> result,
			Collection<TbaseInputSelected> resource) {
		for (TbaseInputSelected c : resource) {
			if (s.getFid().equals(c.getFparentid())) {
				if (!result.contains(c)) {
					result.add(c);
					addChildren(c, result, resource);
				}
			}
		}
	}

	protected void doSave() {
		List<TbaseInputSelectedItem> oldItems = null, newItems = null, delItems = null;
		boolean valdate = false;
		TbaseInputSelected bis = null;
		if (tree.getSelection().length > 0) {
			bis = (TbaseInputSelected) tree.getSelection()[0].getData();
			if (new Long(0).equals(bis.getFisDir())) {
				valdate = true;
				oldItems = BaseResource.getBaseInputSelectedItems(bis.getFid());
			}
		}

		if (!valdate)
			return;
		// 构建新的 items
		newItems = new ArrayList<TbaseInputSelectedItem>();
		TbaseInputSelectedItem tis;
		Long idx = 1L;
		for (TableItem item : table.getItems()) {
			if (item.getData() != null) {
				tis = (TbaseInputSelectedItem) item.getData();
				tis.setId(new TbaseInputSelectedItemId(bis.getFid(), idx++));
			} else {
				tis = new TbaseInputSelectedItem();
				tis.setId(new TbaseInputSelectedItemId(bis.getFid(), idx++));
			}
			tis.setFtext(item.getText(1));
			tis.setFvalue(item.getText(2));
			newItems.add(tis);
		}

		// 找出删除的 items
		boolean del = true;
		if (oldItems != null && oldItems.size() > 0) {
			delItems = new ArrayList<TbaseInputSelectedItem>();
			for (TbaseInputSelectedItem o : oldItems) {
				del = true;
				for (TbaseInputSelectedItem n : newItems) {
					if (o.getId().getFidx().equals(n.getId().getFidx())) {
						del = false;
						break;
					}
				}
				if (del) {
					delItems.add(o);
				}
			}
		}

		try {
			if (newItems.size() > 0)
				service.saveOrUpdateAll(newItems);
			if (delItems != null && delItems.size() > 0)
				service.deleteAll(delItems);
			MessageDialog.openInformation(shell, "提示", "保存成功");
		} catch (BusinessException e) {
			MessageDialog.openConfirm(shell, "保存失败", e.getMessage());
			e.printStackTrace();
		}
	}

	protected void doDelItem() {
		if (table.getSelection().length > 0) {
			table.getSelection()[0].dispose();
		}
	}

	protected void doAddItem() {
		TableItem item = new TableItem(table, SWT.NONE);
		table.setSelection(item, 1);
	}

	protected void doSlected() {
		if (tree.getSelection().length > 0) {
			TbaseInputSelected bis = (TbaseInputSelected) tree.getSelection()[0]
					.getData();
			table.removeAll();
			if (new Long(0).equals(bis.getFisDir())) {
				List<TbaseInputSelectedItem> subItems = BaseResource
						.getBaseInputSelectedItems(bis.getFid());

				for (TbaseInputSelectedItem item : subItems) {
					TableItem i = new TableItem(table, SWT.NONE);
					i.setText(1, toString(item.getFtext()));
					i.setText(2, toString(item.getFvalue()));
					i.setData(item);
				}
				btns.setEnabled(true);
			} else {
				btns.setEnabled(false);
			}
		}
	}

	private String toString(Object obj) {
		String result = "";
		if (obj instanceof String) {
			result = (String) obj;
		}
		return result.trim();
	}

	private Map<Long, TreeItem> items = new HashMap<Long, TreeItem>();

	private void fillTree(Collection<TbaseInputSelected> list) throws Exception {
		tree.removeAll();
		table.removeAll();
		items.clear();
		for (TbaseInputSelected i : list) {
			if (!items.containsKey(i.getFid()))
				buildItem(i);
		}
	}

	private TreeItem buildItem(TbaseInputSelected i) throws Exception {
		TreeItem pItem = null;
		TreeItem item;
		if (ValueUtil.hasValue(i.getFparentid())) {
			if (items.containsKey(i.getFparentid())) {
				pItem = items.get(i.getFparentid());
				TbaseInputSelected parent = (TbaseInputSelected) pItem
						.getData();
				if (i.getFid().equals(parent.getFparentid())) {
					throw new Exception("数据重复递归  : TbaseInputSelected "
							+ i.getFid());
				}
			} else {
				TbaseInputSelected parent = BaseResource.getInputSelected(i
						.getFparentid() + "");
				if (i.getFid().equals(parent.getFparentid())) {
					throw new Exception("数据重复递归  : TbaseInputSelected "
							+ i.getFid());
				} else {
					pItem = buildItem(parent);
				}
			}
		}
		item = pItem != null ? new TreeItem(pItem, SWT.NONE) : new TreeItem(
				tree, SWT.NONE);
		item.setText(i.getFname());
		item.setData(i);
		if (new Long(1).equals(i.getFisDir())) {
			item.setImage(imageFolder);
		} else if (new Long(0).equals(i.getFisDir())) {
			item.setImage(imageFile);
		}
		items.put(i.getFid(), item);
		return item;
	}

}
